{% extends "bootstrap/base.html" %}

{% block title %}语音识别模型基准测试系统{% endblock %}

{% block head %}
{{ super() }}
<link rel="shortcut icon" href="{{ url_for('static',filename='favicon.ico') }}" type="image/x-icon">
<link rel="icon" href="{{ url_for('static',filename='favicon.ico') }}" type="image/x-icon">
<link rel="stylesheet" type="text/css" href="{{ url_for('static',filename='styles.css') }}">
<script src="{{ url_for('static',filename='jquery-3.6.0.min.js')}}" type="text/javascript"></script>
<script src="{{ url_for('static',filename='socket.io.3.0.0.min.js')}}" type="text/javascript"></script>
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
{% endblock %}

{% block navbar %}
<a name="top"></a>
<div class="navbar navbar-inverse" role="navigation">
    <div style="position:fixed;background-color: black;z-index: 1000; width: 100%">
        <div class="navbar-header">
            <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
                <span class="sr-only">Toggle navigation</span>
                <span class="icon-bar"></span>
                <span class="icon-bar"></span>
                <span class="icon-bar"></span>
            </button>
            <a class="navbar-brand" href="{{ url_for('main.index') }}">语音识别模型基准测试系统</a>
        </div>
        <div class="navbar-collapse collapse">
            <ul class="nav navbar-nav">
                <li class="dropdown">
                    <a href="#" class="dropdown-toggle" data-toggle="dropdown">测试数据管理 <b class="caret"></b></a>
                    <ul class="dropdown-menu">
                        <li><a href="{{ url_for('main.bt_service') }}">基准测试执行接口</a></li>
                        <li><a href="{{ url_for('main.dataset') }}">语音数据集</a></li>
                        <li><a href="{{ url_for('main.fpfe') }}">语音的前端处理器和特征提取器</a></li>
                        <li><a href="{{ url_for('main.data_preprocessor') }}">模型的数据预处理器</a></li>
                        <li><a href="{{ url_for('main.acoustic_model') }}">声学模型组件</a></li>
                        <li><a href="{{ url_for('main.lexicon_dict') }}">发音字典组件</a></li>
                        <li><a href="{{ url_for('main.lm') }}">语言模型组件</a></li>
                        <li><a href="{{ url_for('main.decoder') }}">解码器组件</a></li>
                        <li><a href="{{ url_for('main.model') }}">语音识别模型</a></li>
                        <li><a href="{{ url_for('main.post_processor') }}">模型的后处理器</a></li>
                        <li><a href="{{ url_for('main.test_project') }}">测试项目</a></li>
                        <li><a href="{{ url_for('main.bt_task') }}">语音识别模型的基准测试用例</a></li>
                    </ul>
                </li>
                <li class="dropdown">
                    <a href="#" class="dropdown-toggle" data-toggle="dropdown">基准测试任务 <b class="caret"></b></a>
                    <ul class="dropdown-menu">
                        <li><a href="{{ url_for('main.current_bttask') }}">查看执行中的任务</a></li>
                        <li><a href="{{ url_for('main.bttask_queue') }}">查看任务队列</a></li>
                        <li><a href="{{ url_for('main.bttask_exec_history') }}">查看任务执行记录</a></li>
                        <li><a href="{{ url_for('main.bt_result') }}">查看基准测试结果</a></li>
                    </ul>
                </li>
                <li class="dropdown">
                    <a href="#" class="dropdown-toggle" data-toggle="dropdown">基准测试运行环境管理 <b class="caret"></b></a>
                    <ul class="dropdown-menu">
                        <li><a href="{{ url_for('main.upload_file') }}">上传文件</a></li>
                        <li><a href="{{ url_for('main.config') }}">配置管理</a></li>
                        <li><a href="{{ url_for('main.celery_dashboard') }}">查看celery框架的运行信息</a></li>
                        <li><a href="{{ url_for('main.celery_worker_log') }}">查看celery日志</a></li>
                        <li><a href="{{ url_for('main.influxdb_data_vis') }}">查询InfluxDB数据库</a></li>
                    </ul>
                </li>
                <li class="dropdown">
                    <a href="#" class="dropdown-toggle" data-toggle="dropdown">系统操作 <b class="caret"></b></a>
                    <ul class="dropdown-menu">
                        <li><a href="{{ url_for('main.purge_celery_tasks') }}">清空后台任务队列</a></li>
                        <li>
                            <a href="{{ url_for('main.sys_exit') }}">退出系统</a>
                        </li>
                    </ul>
                </li>
                {% if current_user.is_administrator() %}
                <li class="dropdown">
                    <a href="{{ url_for('main.users') }}" class="dropdown-toggle" data-toggle="dropdown">管理用户</a>
                </li>
                {% endif %}
                <li class="dropdown"><a href="#" id="offline-info"></a></li>
                <li class="dropdown"><a href="#" id="client-con-info"></a></li>
            </ul>
            <ul class="nav navbar-nav navbar-right">
                {% if current_user.is_authenticated %}
                <li class="dropdown">
                    <a href="#" class="dropdown-toggle" data-toggle="dropdown">
                        <img class="img-rounded profile-thumbnail" src="{{ current_user.gravatar(size=256) }}" style="width:16px;height:16px">
                        <span style="float:right;padding-left: 18px;">{{ current_user.name }} <b class="caret"></b></span>
                    </a>
                    <ul class="dropdown-menu">
                        <li><a href="{{ url_for('auth.change_password') }}">修改密码</a></li>
                        <li><a href="{{ url_for('main.user',id=current_user.id) }}">我的信息</a></li>
                        <li><a href="{{ url_for('auth.logout') }}">登出</a></li>
                    </ul>
                </li>
                {% else %}
                <li class="dropdown">
                    <a href="{{ url_for('auth.login') }}">登录</a>
                </li>
                <li class="dropdown">
                    <a href="{{ url_for('auth.register') }}">注册</a>
                </li>
                {% endif %}
            </ul>
        </div>
    </div>
</div>
{% endblock %}

{% block content %}
<div class="container">
    {% for message in get_flashed_messages() %}
    <div class="alert alert-warning">
        <button type="button" class="close" data-dismiss="alert">&times;</button>
        {{ message }}
    </div>
    {% endfor %}
    <div style="position:fixed;top:50px;right:40px;background-color: #ccc;z-index: 9999;width:450px;height:700px;" id="task_info">
        <button id="collapseBtn" style="z-index:999;"></button>
        <a href="#top"><button style="z-index:999;">返回顶部</button></a>
        <div id="status-info">
            <h6>当前正在执行的后台任务</h6>
            <div id="celery-tasks-div"></div>
            <h6>基准测试任务列表 <a href="{{ url_for('main.bttask_queue') }}">管理任务队列</a></h6>
            <div id="bt-tasks-div"></div>
        </div>
        <div id="res-div">
            <p id="manage-bttask-state-p" style="color:aquamarine"></p>
            <p id="bttask-exec-state-p" style="color:blue"></p>
            <p id="rest-duration-and-progress-p" style="color:rgb(229, 36, 26)"></p>
        </div>
    </div>
    {% block page_content %}{% endblock %}
</div>
{% endblock %}

{% block scripts %}
{{ super() }}
{{ moment.include_moment() }}
{{ moment.lang("zh-CN") }}
<script type="text/javascript">

    const statuses=['发布中','待执行','更新中','暂停中','已完成','被舍弃','执行中','执行出现错误','已提交','正在中止','正在取消'];
    const collapseBtn=document.getElementById('collapseBtn');
    const statusInfoDiv=document.getElementById('status-info');
    const resDiv=document.getElementById('res-div');

    function showCeleryTasks(celery_tasks){
        console.log(celery_tasks);
        if(celery_tasks.length==0){
            $('#celery-tasks-div').html('<p>暂时没有正在执行的后台任务</p>');
        }else{
            let div_html='';
            for(let i=0;i<celery_tasks.length;i++){
                div_html+='<p>'+celery_tasks[i]+'</p>';
            }
            $('#celery-tasks-div').html(div_html);
        }
    }

    function showBTTasks(bt_tasks){
        console.log(bt_tasks);
        if(bt_tasks.length==0){
            $('#bt-tasks-div').html('<p>任务队列中暂时没有基准测试任务</p>');
        }else{
            let div_html='';
            for(let i=0;i<bt_tasks.length;i++){
                div_html+='<p>';
                if(bt_tasks[i][5]==-1){
                    div_html+='用例<a href="/btt/'+bt_tasks[i][0]+'">'+bt_tasks[i][2];
                }else{
                    div_html+='任务<a href="/btresults/'+bt_tasks[i][5]+'">'+bt_tasks[i][6];
                }
                div_html+='</a> '+statuses[bt_tasks[i][1]]+' '+bt_tasks[i][3]+'</p>';
            }
            $('#bt-tasks-div').html(div_html);
        }
    }

    function update_status_url(url,div_id){
        if(url=='not ok')return;
        $.getJSON(url,function(data){
            if('result' in data){
                $('#'+div_id+'_result_div').text(data['time']+' '+data['status']+' '+data['result']);
            }else{
                $('#'+div_id+'_result_div').text(data['time']+' '+data['state']+data['status']);
            }
            if(data['state']=='PENDING'||data['state']=='PROGRESS'){
                setTimeout(function(){
                    update_status_url(url,div_id);
                },1000);
            }
        });
    }

    function heartbeat(){
        $.ajax({
            type:'GET',
            url:'/exec/heartbeat',
            timeout:5000,
            success:function(data,status,request){
                $('#offline-info').text('');
                setTimeout(function(){
                    heartbeat();
                },10000);
            },
            error:function(){
                alert('请求系统心跳的过程中出现错误');
                setTimeout(function(){
                    heartbeat();
                },100000);
            },
            complete:function(request,status){
                if(status=='timeout'){
                    $('#offline-info').text('系统可能宕机，请重启');
                }
            }
        });
    }

    function client_heartbeat(){
        $.ajax({
            type:'GET',
            url:'/client_heartbeat',
            success:function(data,status,request){
                if(data['data']==1){
                    $('#client-con-info').text('客户端已连接');
                }else{
                    $('#client-con-info').text('客户端已断开连接');
                }
                setTimeout(function(){
                    client_heartbeat();
                },60000);
            },
            error:function(){
                alert('请求客户端心跳的过程中出现错误');
                setTimeout(function(){
                    client_heartbeat();
                },100000);
            }
        });
    }

    $(document).ready(function(){
        $.getJSON('/get_celery_tasks',function(data){
            let celery_tasks=data['data'];
            showCeleryTasks(celery_tasks);
        });
        $.getJSON('/get_bt_tasks',function(data){
            let bt_tasks=data['data'];
            showBTTasks(bt_tasks);
        });
        // $.getJSON('/get_first_req_times',function(data){
        //     let first_req_times=data['data'];
        //     showFirstReqTimes(first_req_times);
        // })
        namespace='/status';
        var socket=io.connect(location.protocol+'//'+document.domain+':'+location.port+namespace);
        socket.on('celery_tasks',function(res){
            var celery_tasks=res.data;
            showCeleryTasks(celery_tasks);
        });
        socket.on('bt_tasks',function(res){
            var bt_tasks=res.data;
            showBTTasks(bt_tasks);
        });
        socket.on('manage_bttask_state',function(res){
            $('#manage-bttask-state-p').text(res.manage_bttask_state);
        });
        socket.on('bttask_exec_state',function(res){
            $('#bttask-exec-state-p').text(res.bttask_exec_state);
        })
        socket.on('rest_duration_and_progress',function(res){
            if(res.rest_duration>=0){
                $('#rest-duration-and-progress-p').text('完成任务还需要'+res.rest_duration+'s时间，进度'+res.progress+'%');
            }else{
                $('#rest-duration-and-progress-p').text('暂时未知任务的进度及其完成仍需花费的时间');
            }
        });
        heartbeat();
        client_heartbeat();
        $.ajax({
            type:'GET',
            url:'/exec/b_collapse',
            success:function(data,status,request){
                if(data['data']){
                    statusInfoDiv.setAttribute('style','display:none;');
                    resDiv.setAttribute('style','display:none;');
                    $('#collapseBtn').text('扩展');
                    $('#task_info').attr('style','position:fixed;top:50px;right:40px;background-color: #ccc;z-index: 9999;width:450px;height:27px;');
                }else{
                    statusInfoDiv.setAttribute('style','display:block;');
                    resDiv.setAttribute('style','display:block;');
                    $('#collapseBtn').text('折叠');
                    $('#task_info').attr('style','position:fixed;top:50px;right:40px;background-color: #ccc;z-index: 9999;width:450px;height:700px;');
                }
            },
            error:function(){
                alert('请求是否要展开任务运行通知栏的过程中出现错误');
            }
        });
        $.getJSON('/get_manage_bttask_state',function(data){
            console.log(data['manage_bttask_state']);
            $('#manage-bttask-state-p').text(data['manage_bttask_state']);
        });
        $.getJSON('/get_bttask_exec_state',function(data){
            console.log(data['bttask_exec_state']);
            $('#bttask-exec-state-p').text(data['bttask_exec_state']);
        });
        $.getJSON('/get_rest_duration_and_progress',function(data){
            console.log(data['rest_duration']);
            if(data['rest_duration']>=0){
                $('#rest-duration-and-progress-p').text('完成任务还需要'+data['rest_duration']+'s时间，进度'+data['progress']+'%');
            }else{
                $('#rest-duration-and-progress-p').text('暂时未知任务的进度及其完成仍需花费的时间');
            }
        });
    });

    collapseBtn.onclick=()=>{
        console.log($('#collapseBtn').text())
        if($('#collapseBtn').text()=='折叠'){
            statusInfoDiv.setAttribute('style','display:none;');
            resDiv.setAttribute('style','display:none;');
            $('#collapseBtn').text('扩展');
            $('#task_info').attr('style','position:fixed;top:50px;right:40px;background-color: #ccc;z-index: 9999;width:450px;height:27px;');
            $.ajax({
                type:'GET',
                url:'/exec/collapse'
            });
        }else{
            statusInfoDiv.setAttribute('style','display:block;');
            resDiv.setAttribute('style','display:block;');
            $('#collapseBtn').text('折叠');
            $('#task_info').attr('style','position:fixed;top:50px;right:40px;background-color: #ccc;z-index: 9999;width:450px;height:700px;');
            $.ajax({
                type:'GET',
                url:'/exec/notCollapse'
            });
        }
    };
</script>
{% endblock %}